/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** *****************************************************************************************************
 *  \file     Port_Ip.h                                                                                 *
 *  \brief    Semidrive. AUTOSAR 4.3.1 MCAL Port_IP Driver                                              *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2023/07/14     <td>1.0.0                                                                     *
 * </table>                                                                                             *
 *******************************************************************************************************/

#ifndef PORT_IP_H
#define PORT_IP_H
#ifdef __cplusplus
extern "C" {
#endif

/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/
#include "Std_Types.h"
#include "RegHelper.h"
#include "Port_Cfg.h"

/********************************************************************************************************
 *                                 Global Macro definition                                              *
 *******************************************************************************************************/

/* PORT PIN MUX CONFIG REGISTER */
#define PORT_MUX_CONFIG_REG_OFFSET      (0x2000U)
#define MUX_FUNC_SHIFT                  (0U)
#define MUX_FUNC_WIDTH                  (4U)
#define MUX_ODE_SHIFT                   (4U)
#define MUX_ODE_WIDTH                   (1U)
#define MUX_FIN_SHIFT                   (8U)
#define MUX_FIN_WIDTH                   (2U)
#define MUX_FIN_IP_SHIFT                (10U)
#define MUX_FIN_IP_WIDTH                (16U)
#define MUX_FV_SHIFT                    (29U)
#define MUX_FV_WIDTH                    (1U)
#define MUX_DO_FORCE_EN_SHIFT           (30U)
#define MUX_DO_FORCE_EN_WIDTH           (1U)
#define MUX_DO_FORCE_VALUE_SHIFT        (31U)
#define MUX_DO_FORCE_VALUE_WIDTH        (1U)

/* PORT PAD CONFIG REGISTER */
#define PORT_PAD_CONFIG_REG_OFFSET      (0x1000U)
#define PAD_PULL_SHIFT                  (0U)
#define PAD_PULL_WIDTH                  (2U)
#define PAD_DS_SHIFT                    (4U)
#define PAD_DS_WIDTH                    (2U)
#define PAD_SR_SHIFT                    (8U)
#define PAD_SR_WIDTH                    (1U)
#define PAD_IS_SHIFT                    (12U)
#define PAD_IS_WIDTH                    (1U)
#define PAD_POE_SHIFT                   (16U)
#define PAD_POE_WIDTH                   (1U)
#define PAD_MS_SHIFT                    (20U)
#define PAD_MS_WIDTH                    (1U)

/* PORT INPUT SELECT REGISTER */
#define PORT_INPUT_SELECT_REG_OFFSET    (0x3000U)
#define INPUT_SELECT_SRC_SEL_SHIFT      (0U)
#define INPUT_SELECT_SRC_SEL_WIDTH      (4U)

/* Force input ON/OFF.*/
#define PAD_INPUT_NO_FORCE           (0x0U) /* Pad input/output is selected by ALT function.*/
#define PAD_INPUT_FORCE_ENABLE       (0x1U) /* Enable pad input, regardless of ALT function.*/
#define PAD_INPUT_FORCE_DISABLE      (0x2U) /* Disable pad input. Internal IP read the value of FORCE_INPUT bit.*/

/* Force input value. Used in PAD_INPUT_FORCE_DISABLE mode. */
#define PAD_FORCE_INPUT_VALUE_0      (0U)   /*Force input value is 0*/
#define PAD_FORCE_INPUT_VALUE_1      (1U)   /*Force input value is 1*/

/* Force input IP mux sel.*/
#define PAD_INPUT_IP_NO_MUX_FORCE           (0x0000U) /* No ip Force inpute.*/
#define PAD_INPUT_IP_MUX0_FORCE_ENABLE      (0x0001U) /* ALT0 function Force inpute. (GPIO) */
#define PAD_INPUT_IP_MUX1_FORCE_ENABLE      (0x0002U) /* ALT1 function Force inpute.*/
#define PAD_INPUT_IP_MUX2_FORCE_ENABLE      (0x0004U) /* ALT2 function Force inpute.*/
#define PAD_INPUT_IP_MUX3_FORCE_ENABLE      (0x0008U) /* ALT3 function Force inpute.*/
#define PAD_INPUT_IP_MUX4_FORCE_ENABLE      (0x0010U) /* ALT4 function Force inpute.*/
#define PAD_INPUT_IP_MUX5_FORCE_ENABLE      (0x0020U) /* ALT5 function Force inpute.*/
#define PAD_INPUT_IP_MUX6_FORCE_ENABLE      (0x0040U) /* ALT6 function Force inpute.*/
#define PAD_INPUT_IP_MUX7_FORCE_ENABLE      (0x0080U) /* ALT7 function Force inpute.*/
#define PAD_INPUT_IP_MUX8_FORCE_ENABLE      (0x0100U) /* ALT8 function Force inpute.*/
#define PAD_INPUT_IP_MUX9_FORCE_ENABLE      (0x0200U) /* ALT9 function Force inpute.*/
#define PAD_INPUT_IP_MUX10_FORCE_ENABLE     (0x0400U) /* ALT10 function Force inpute.*/
#define PAD_INPUT_IP_MUX11_FORCE_ENABLE     (0x0800U) /* ALT11 function Force inpute.*/
#define PAD_INPUT_IP_MUX12_FORCE_ENABLE     (0x1000U) /* ALT12 function Force inpute.*/
#define PAD_INPUT_IP_MUX13_FORCE_ENABLE     (0x2000U) /* ALT13 function Force inpute.*/
#define PAD_INPUT_IP_MUX14_FORCE_ENABLE     (0x4000U) /* ALT14 function Force inpute.*/
#define PAD_INPUT_IP_MUX15_FORCE_ENABLE     (0x8000U) /* ALT15 function Force inpute.*/

/* DO_Force ON/OFF.*/
#define PAD_OUTPUT_FORCE_DISABLE      (0x0U) /* Disable Force output, PAD fault status configuration disable.*/
#define PAD_OUTPUT_FORCE_ENABLE       (0x1U) /* Enable Force output, PAD fault status configuration enable.*/

/* DO_Force value. Used in PAD_OUTPUT_FORCE_ENABLE mode. */
#define PAD_FORCE_OUTPUT_VALUE_0      (0U)   /*When in a PAD fault state, the forced output value is 0.*/
#define PAD_FORCE_OUTPUT_VALUE_1      (1U)   /*When in a PAD fault state, the forced output value is 1.*/

/* PORT GPIO CONFIG REGISTER */
#define PORT_GPIO_OEN                   (0x580U) /*gpio output enable*/
#define PORT_GPIO_DATA_IN               (0x600U) /*gpio data input*/
#define PORT_GPIO_DATA_OUT              (0x680U) /*gpio data output*/
#define PORT_GPIO_SINT_EN               (0x700U) /*gpio sync interrupt enable*/
#define PORT_GPIO_SINT_MASK             (0x780U) /*gpio sync interrupt mask*/
#define PORT_GPIO_SINT_TYPE             (0x800U) /*gpio sync interrupt type*/
#define PORT_GPIO_SINT_POL              (0x880U) /*gpio sync interrupt polarity*/
#define PORT_GPIO_SINT_BOTH_EDGE        (0x900U) /*gpio sync interrupt both edge enable*/
#define PORT_GPIO_SINT_STATUS           (0x980U) /*gpio sync interrupt status*/
#define PORT_GPIO_SINT_STATUS_UNMAS     (0xA00U) /*gpio sync interrupt unmask status*/
#define PORT_GPIO_SINT_EDGE_CLR         (0xA80U) /*gpio sync interrupt clear*/
#define PORT_GPIO_AINT_EN               (0xB00U) /*gpio async interrupt enable*/
#define PORT_GPIO_AINT_MASK             (0xB80U) /*gpio async interrupt mask*/
#define PORT_GPIO_AINT_TYPE             (0xC00U) /*gpio async interrupt type*/
#define PORT_GPIO_AINT_POL              (0xC80U) /*gpio async interrupt polarity*/
#define PORT_GPIO_AINT_BOTH_EDGE        (0xD00U) /*gpio async interrupt both edge enable*/
#define PORT_GPIO_AINT_STATUS           (0xD80U) /*gpio async interrupt status*/
#define PORT_GPIO_AINT_STATUS_UNMAS     (0xE00U) /*gpio async interrupt unmask status*/
#define PORT_GPIO_AINT_EDGE_CLR         (0xE80U) /*gpio async interrupt clear*/

/* PORT GPIO CONFIG REGISTER */
#define PORT_SET_PIN                    (0x04U)   /*gpio set offset*/
#define PORT_CLEAR_PIN                  (0x08U)   /*gpio clear offset*/
#define PORT_TOGGLE_PIN                 (0x0CU)   /*gpio toggle offset*/

/**
 * PORT GPIO INDEX.
 * define channel register bit operation, All channel(0-213) can be operate.
 */
#define PORT_PIN_OFFSET(channelId) ((channelId) / 32U)
#define PORT_PIN_BIT(channelId) ((channelId) % 32U)
#define PORT_PIN_MASK(channelId) (1UL << PORT_PIN_BIT(channelId))

/* PORT GPIO operate register define */
#define PORT_GPIO_SIZE 0x10U                                    /* gpio group register size*/
#define PORT_GPIO_OFFSET(base, n) ((base) + ((n)*PORT_GPIO_SIZE)) /* gpio group register address offset*/

/* GPIO PORT Interrupt Type */
#define PORT_INT_TYPE_LEVEL     (0x0UL)
#define PORT_INT_TYPE_PULSE     (0x1UL)
#define PORT_INT_POL_LOW_NEG    (0x0UL)
#define PORT_INT_POL_HIGH_POS   (0x1UL)
#define PORT_INT_BOE_SIG_EDGE   (0x0UL)
#define PORT_INT_BOE_BOTH_EDGE  (0x1UL)


/********************************************************************************************************
 *                                  Global Types definition                                             *
 *******************************************************************************************************/

/* Configuration options of a port pin */
typedef enum
{
    /* PAD function. */
    PORT_CONFIG_FUNCTION = 0U,
    /* Pull up, pull down, or no-pull. */
    PORT_CONFIG_PULL,
    /* Open drain or push pull. */
    PORT_CONFIG_DRIVE,
    /* Drive strength. */
    PORT_CONFIG_DRIVE_STRENGTH,
    /* Enable schmitt-trigger input mode. */
    PORT_CONFIG_INPUT_SCHMITT,
    /* Slew rate. */
    PORT_CONFIG_SLEW_RATE,
    /* Force input. */
    PORT_CONFIG_FORCE_INPUT,
    /* Force output. */
    PORT_CONFIG_FORCE_OUTPUT,
    /* Mode select, analog digital combo io only */
    PORT_CONFIG_MODE_SELECT,
    PORT_CONFIG_MAX,
} Port_PinConfigType;

/********************************************************************************************************
 *                                  Global Function Declarations                                        *
 *******************************************************************************************************/
/** *****************************************************************************************************
 * \brief This function is internal interface for port init.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_Init(const Port_SettingsConfigType* settingsPtr, uint16 num)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : settingsPtr - Pointer to the init configuration settings
 *                      num - init configuration settings number
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for port init.
 * \endverbatim
 * Traceability       : SWSR_PORT_003 SWSR_PORT_004 SWSR_PORT_005 SWSR_PORT_006
 *                      SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055 SWSR_PORT_056
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_Init(const Port_SettingsConfigType *settingsPtr, uint16 num);
#if (PORT_ANALOG_PIN_ENABLE == STD_ON)
/** *****************************************************************************************************
 * \brief This function is internal interface for analog port init.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_AnalogPadInit
 *                                      (const Port_AnalogConfigType* settingsPtr, const uint16 num)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : settingsPtr - Pointer to the init analog configuration settings
 *                      num - init analog configuration settings number
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for analog port init.
 *                      This function is available if the PORT_ANALOG_PIN_ENABLE is set STD_ON
 * \endverbatim
 * Traceability       : SWSR_PORT_003 SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_055
 *                      SWSR_PORT_056 SWSR_PORT_006 SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_AnalogPadInit(const Port_AnalogConfigType *settingsPtr, const uint16 num);
#endif   /** #if (PORT_ANALOG_PIN_ENABLE == STD_ON)*/

#if (PORT_SET_PIN_DIRECTION_API == STD_ON)
/** *****************************************************************************************************
 * \brief This function is internal interface for set direction of Dio pads at runtime.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_SetPinDirection
 *                        (Port_PinType pin, Port_PinDirectionType direction,
 *                         const Port_SettingsConfigType* cfgPtr, uint16 num)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - the pin which direction to be set
 *                      direction - the direction to be set, 0 for input and 1 for output.
 *                      cfgPtr - the pointer to the init configuration, used to check pin direction changable
 *                      num - the number of the init configuration
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for set direction of Dio pads at runtime.
 *                      Only gpio pins which pin direct changable can be modifed.
 *                      This function is available if the PORT_SET_PIN_DIRECTION_API is set STD_ON
 * \endverbatim
 * Traceability       : SWSR_PORT_005 SWSR_PORT_008 SWSR_PORT_017 SWSR_PORT_018
 *                      SWSR_PORT_055 SWSR_PORT_056 SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_SetPinDirection(Port_PinType pin, Port_PinDirectionType direction,
                                       const Port_SettingsConfigType *cfgPtr, uint16 num);
#endif  /** #if (PORT_SET_PIN_DIRECTION_API == STD_ON)*/
/** *****************************************************************************************************
 * \brief This function is internal interface for refresh the pin direction of Dio pads at runtime.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_RefreshPortDirection
 *                                          (const Port_SettingsConfigType* cfgPtr, uint16 num)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : cfgPtr - the pointer to the init configuration, used to check pin direction changable
 *                      num - the number of the init configuration
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for refresh the pin direction of Dio pads at runtime.
 *                      Only gpio pins which pin direct not changable can be refreshed.
 * \endverbatim
 * Traceability       : SWSR_PORT_005  SWSR_PORT_010 SWSR_PORT_017 SWSR_PORT_018
 *                      SWSR_PORT_046  SWSR_PORT_047 SWSR_PORT_055 SWSR_PORT_056
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_RefreshPortDirection(const Port_SettingsConfigType *cfgPtr, uint16 num);

#if (STD_ON == PORT_SET_PIN_MODE_API)
/** *****************************************************************************************************
 * \brief This function is internal interface for set pin mode at runtime.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Port_Ip_SetPinMode(Port_PinType pin, Port_PinModeType mode,
 *                                                      const Port_SettingsConfigType* cfgPtr, uint16 num);
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : pin - the pin which mode to be set
 *                      mode - the mode to be set, PORT_PIN_MUX_ALT0~PORT_PIN_MUX_ALT9
 *                      cfgPtr - the pointer to the init configuration, used to check pin mode changable
 *                      num - the number of the init configuration
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : ErrorId
 *
 * Description        : This function is internal interface for set pin mode at runtime.
 *                      Only pin which mode changable can be modifed.
 *                      This function is available if the PORT_SET_PIN_MODE_API is set STD_ON
 * \endverbatim
 * Traceability       : SWSR_PORT_005 SWSR_PORT_017 SWSR_PORT_018 SWSR_PORT_051
 *                      SWSR_PORT_052 SWSR_PORT_053 SWSR_PORT_055 SWSR_PORT_056
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Port_Ip_SetPinMode(Port_PinType pin, Port_PinModeType mode,
                                  const Port_SettingsConfigType *cfgPtr, uint16 num);
#endif  /** #if (STD_ON == PORT_SET_PIN_MODE_API)*/
#ifdef __cplusplus
}
#endif
/* End of file */
#endif /* PORT_IP_H */
